import { defineStore } from 'pinia'
// 导入串口第三方库
const { SerialPort } = window.require('serialport')

// 导入ipcRenderer,用于和electron主线程通信
// const { ipcRenderer } = window.require('electron')

import { useMessage } from '@renderer/hooks/message'
import { useOfflineBurningMode } from '@renderer/hooks/offlineBurningMode'
import { useFilereader } from '@renderer/hooks/fileReader'
import { useCommonTools } from '@renderer/hooks/commonTools'

const messageTip = useMessage()
const offlineBurningModeHook = useOfflineBurningMode()
const fileReaderHook = useFilereader()
const commonTools = useCommonTools()

interface portInterface {
    open: Function
    close: Function
    on: Function
    write: Function
}

export const usePortsStore = defineStore({
    id: 'portsStore',
    state: () => ({
        // true： 通用 false： CAN
        isUart: true,
        // 仪表连接状态  0未接入  1已接入
        modelOnlineStatus: 0,
        // 串口状态 0：等待连接 1: 连接中  2： 已连接 
        portsStatus: 0,
        // 比特率
        currentBaud: 9600,
        // 数据位
        currentDataBit: 8,
        // 校验位
        currentVaild: 'none',
        // 串口列表
        serialPortList: [] as any[],
        // 当前串口
        currentSerialPort: '',
        port: {} as portInterface,
        serialData: [],
        timer: null as any,
        canHeartBeatTimer: null as any,
        canPauseHeartTimer: null as any,
        canHeartCodeCount: 0,
        timeoutId: null as any, // 定时器ID
    }),
    getters: {
        isModleNoDisabled(state) {
            return (state.portsStatus === 2 && state.modelOnlineStatus !== 0)
        }
    },
    actions: {
        // 获取串口列表
        async getSerialPorts() {
            this.serialPortList = await SerialPort.list()
        },
        async handleSerialPort() {
            // 获取选中的串口
            if (this.portsStatus !== 0) {
                this.port && this.port?.close()
                this.portsStatus = 0;
            } else {
                // 连接串口,配置对应的数据
                this.port = new SerialPort({
                    // 连接的串口信息数据
                    path: this.currentSerialPort,
                    // 比特率
                    baudRate: this.currentBaud,
                    // 数据位
                    dataBits: this.currentDataBit,
                    // 奇偶校验位
                    parity: this.currentVaild,
                    // 停止位
                    stopBits: 1,
                    autoOpen: false
                });

                await this.port.open({ openImmediately: false })
                this.portsStatus = 2;

                this.port?.on('data', (data) => {
                    console.log('data数据', data);
                    this.modelOnlineStatus = 1;
                    this.onDataReceived(data)
                    this.resetOfflineTimer();
                })

                this.port.on('error', (err) => {
                    console.log('err', err)
                    // 串口正在打开错误不提示
                    if (err.toString() === 'Error: Port is opening') {
                        this.portsStatus = 1
                        return
                    }
                    this.portsStatus = 0;
                    this.modelOnlineStatus = 0;
                    if (this.timeoutId) {
                        clearTimeout(this.timeoutId)
                    }
                    if (this.canHeartBeatTimer) {
                        clearInterval(this.canHeartBeatTimer)
                    }
                    messageTip.error(err);
                })

                this.port.on('close', () => {
                    console.log('串口已断开');
                    this.portsStatus = 0;
                    this.modelOnlineStatus = 0;

                    clearInterval(this.timer)
                    clearTimeout(this.canPauseHeartTimer)

                    if (this.timeoutId) {
                        clearTimeout(this.timeoutId)
                    }
                    if (this.canHeartBeatTimer) {
                        clearInterval(this.canHeartBeatTimer)
                    }
                })
            }
        },
        onDataReceived(data) { },
        // 重置定时器
        resetOfflineTimer() {
            if (this.timeoutId) {
                clearTimeout(this.timeoutId)
            }

            this.timeoutId = setTimeout(() => {
                this.modelOnlineStatus = 0;

                if (this.canHeartBeatTimer) {
                    clearInterval(this.canHeartBeatTimer)
                }
            }, 1000);
        },
        writeMsg(data) {
            console.log(commonTools.Bytes2HexString(data), data)
            this.port.write(data)
        },
        // 发送指令
        cmdSum(cmd, data) {
            let cmdData = [] as number[];
            const CMD_HEAD = 0x55;
            // 命令头
            cmdData.push(CMD_HEAD);
            // 命令字
            cmdData.push(cmd);
            // 数据长度
            cmdData.push(data.length & 0xFF);
            data.forEach(item => cmdData.push(item))
            //校验生成 !!!!从起始符 - 校验码之前
            let d = 0;
            for (let i = 0; i < cmdData.length; i++) {
                d ^= cmdData[i];
            }
            cmdData.push(d);

            return cmdData;
        },
        cmd3aSum(cmd, data) {
            const CMD_HEAD = 0x3A
            const CMD_ADDRESS = 0x1A
            const CMD_END1 = 0x0D
            const CMD_END2 = 0x0A

            let cmdData = [] as number[];
            // 命令头
            cmdData.push(CMD_HEAD);
            // 设备地址
            cmdData.push(CMD_ADDRESS);
            // 命令字
            cmdData.push(cmd);
            // 数据长度
            cmdData.push(data.length & 0xFF);
            // 循环取值
            data.forEach(item => cmdData.push(item))
            //校验生成 !!!!从设备地址 - 校验码之前
            let d = 0;
            for (let i = 1; i < cmdData.length; i++) {
                d += cmdData[i]
            }

            cmdData.push(d & 0xff);
            cmdData.push((d >> 8) & 0xff);
            cmdData.push(CMD_END1);
            cmdData.push(CMD_END2);

            return cmdData;
        },
        // 校验命令字
        checkReceiveData(childCode) {
            switch (childCode[1]) {
                case 0xA0: // Unimaster版本
                    break;
                case 0x16: //  清空升级缓冲区
                    offlineBurningModeHook.clearUpgradTypeFn(childCode);
                    break;
                case 0x30: // 离线烧录 （配置）
                    offlineBurningModeHook.upgradOfflineFileFn(childCode, 3, 8, childCode[1])
                    break;
                case 0x31: // 离线烧录 （ui）
                    offlineBurningModeHook.upgradOfflineFileFn(childCode, 2, 4, childCode[1])
                    break;
                case 0x32: // 离线烧录 （boot）
                    offlineBurningModeHook.upgradOfflineFileFn(childCode, 0, 1, childCode[1])
                    break;
                case 0x33: // 离线烧录 （app）
                    offlineBurningModeHook.upgradOfflineFileFn(childCode, 1, 2, childCode[1])
                    break;
                case 0x34: // 升级项结束写入
                    offlineBurningModeHook.getUpgradEndFn(childCode, childCode[1]);
                    break;
            }
        }
    }
})